#include "candidatewindow.h"
#include "candidateitem.h"
#include "windowutil.h"
#include "configmanager.h"

#include <QApplication>
#include <QDebug>

CandidateWindow::CandidateWindow(QWidget *parent)
   : QWidget(parent)
    , m_selectedIndex(-1)
    , m_candidateCount(5)  // 默认5个候选词（后续从配置更新）
{
	initUI();
	// 无操作5秒后隐藏
	m_hideTimer.setInterval(5000);
	connect(&m_hideTimer, &QTimer::timeout, this, &QWidget::hide);
}

void CandidateWindow::setCandidates(const QVector<PinyinCandidate> &cadidates)
{
	// clear old label
	qDeleteAll(m_candidateLabels);
	m_candidateLabels.clear();
	m_candidates.clear();
	m_selectedIndex = -1;

	// 截断候选词
	m_candidates = cadidates.mid(0, m_candidateCount);
	if (m_candidates.isEmpty()) {
		hide();
		return;
	}
	// new label 使用CandidateItem（支持拼音显示、hover交互）
    for (int i = 0; i < m_candidates.size(); i++) {
        const auto& cand = m_candidates[i];
        CandidateItem *item = new CandidateItem(i, cand, this);
        m_candidateLabels.append(item);
        m_mainLayout->addWidget(item);
        // 候选词选中信号连接
        connect(item, &CandidateItem::candidateSelected, this, [this, i]() {
            emit candidateSelected(m_candidates[i].text);
            hide();
        });
    }
	// 调整窗口大小并显示
    adjustSize();  // 自适应布局大小
	show();
	m_hideTimer.start();
}

void CandidateWindow::moveBelowWidget(QWidget *targetWidget)
{
	if (!targetWidget) return;
    // 调用 platform 模块工具类，将窗口移动到目标控件下方（避免超出屏幕）
    WindowUtil::moveWindowBelow(this, targetWidget);
}

/////////////////////////////////////////////////////////
// overrides
void CandidateWindow::mousePressEvent(QMouseEvent *event)
{
	if (event->button() != Qt::LeftButton) return;
    // 按下鼠标时高亮对应候选词
    int index = getCandidateIndexAt(event->pos());
    highlightSelectedCandidate(index);
    m_hideTimer.start();  // 重置计时器
}

void CandidateWindow::mouseMoveEvent(QMouseEvent *event)
{
	if (!(event->buttons() & Qt::LeftButton)) return;
    // 滑动时实时更新高亮
    int index = getCandidateIndexAt(event->pos());
    highlightSelectedCandidate(index);
    m_hideTimer.start();  // 重置计时器
}

void CandidateWindow::mouseReleaseEvent(QMouseEvent *event)
{
	if (event->button() != Qt::LeftButton || m_selectedIndex == -1) {
        hide();
        return;
    }

    // 释放鼠标时发送选中信号
    QString selectedText = m_candidates[m_selectedIndex].text;
    emit candidateSelected(selectedText);
    hide();
}

void CandidateWindow::resizeEvent(QResizeEvent *event)
{
	Q_UNUSED(event);
    // 窗口大小变化时重新调整布局
    updateCandidateLayout();
}

void CandidateWindow::showEvent(QShowEvent *event)
{
	Q_UNUSED(event);
    m_hideTimer.start();  // 显示时启动计时器
}

void CandidateWindow::hideEvent(QHideEvent *event)
{
	Q_UNUSED(event);
    m_hideTimer.stop();   // 隐藏时停止计时器
    emit windowHidden();  // 发送隐藏信号
}

void CandidateWindow::keyPressEvent(QKeyEvent *event)
{
    if (m_candidates.isEmpty()) {
        return;
    }
    switch (event->key()) {
        case Qt::Key_Up:
            m_selectedIndex = (m_selectedIndex - 1 + m_candidates.size()) % m_candidates.size();
            highlightSelectedCandidate(m_selectedIndex);
            break;
        case Qt::Key_Down:
            m_selectedIndex = (m_selectedIndex + 1) % m_candidates.size();
            highlightSelectedCandidate(m_selectedIndex);
            break;
        case Qt::Key_1 ... Qt::Key_9:
            int index = event->key() - Qt::Key_1;
            if (index < m_candidates.size()) {
                emit candidateSelected(m_candidates[index].text);
                hide();
            }
            break;
        case Qt::Key_Escape:
            hide();
            break;
        default:
            QWidget::keyPressEvent(event);
    }
}

//////////////////////////////////////////////////////////////////
void CandidateWindow::initUI()
{
	// 无边框+阴影+半透明（依赖 WindowUtil）
	WindowUtil::setFramelessWithShadow(this, 8);
	// 半透明
	setAttribute(Qt::WA_TranslucentBackground);
	setStyleSheet(R"(
        CandidateWindow {
            background-color: rgba(255, 255, 255, 0.95);
            border-radius: 8px;
        }
        QLabel {
            padding: 6px 12px;
            font-size: 14px;
            color: #333333;
            border-radius: 4px;
        }
        QLabel:hover {
            background-color: #E6F7FF;
        }
        QLabel:selected {  /* 自定义选中样式 */
            background-color: #1890FF;
            color: white;
        }
    )");

	// 布局
	m_mainLayout = new QHBoxLayout(this);
    m_mainLayout->setContentsMargins(10, 8, 10, 8);
    m_mainLayout->setSpacing(8);
	setFixedHeight(40);	// 宽度自适应(根据候选词len)

	// make sure 从配置读取候选词显示数量（覆盖默认值）
    m_candidateCount = ConfigManager::getInstance()->getInputMethodConfig().candidateCount;
    // 监听配置变更，实时更新候选词数量
    connect(ConfigManager::getInstance(), &ConfigManager::inputMethodConfigChanged, 
            this, [this](const InputMethodConfig::Data& config) {
        m_candidateCount = config.candidateCount;
        if (!m_candidates.isEmpty()) {
            setCandidates(m_candidates);  // 重新加载候选词以应用新数量
        }
    });
}

void CandidateWindow::updateCandidateLayout()
{
	if (m_candidateLabels.isEmpty()) return;
    // 均匀分配每个候选词标签的宽度
    int labelWidth = width() / m_candidateLabels.size();
    for (QLabel* label : m_candidateLabels) {
        label->setFixedWidth(labelWidth);
    }
}

int CandidateWindow::getCandidateIndexAt(const QPoint &pos)
{
	if (m_candidateLabels.isEmpty()) return -1;
	// 等分
	int labelWidth = width() / m_candidateLabels.size();
    int index = pos.x() / labelWidth;
	// 边界校验
    return (index >= 0 && index < m_candidateLabels.size()) ? index : -1;
}

void CandidateWindow::highlightSelectedCandidate(int index)
{
	// @brief 高光选中候选词
	if (index < 0 || index >= m_candidates.size()) {
        for (auto* item : m_candidateLabels) {
            item->setStyleSheet(item->property("defaultStyle").toString());
        }
        m_selectedIndex = -1;
        return;
    }
	// 选中高亮 其他的cancel
	for (int i = 0; i < m_candidateLabels.size(); i++) {
        CandidateItem *item = dynamic_cast<CandidateItem*>(m_candidateLabels[i]);
        if (i == index) {
            item->setStyleSheet(item->property("selectedStyle").toString());
        } else {
            item->setStyleSheet(item->property("defaultStyle").toString());
        }
    }
    m_selectedIndex = index;
}
